﻿#include "MMAV.h"
#include "MMAVPacketPrivate.h"
#include "MMAVReaderPrivate.h"
#include "MMAVStreamPrivate.h"

// 一个类就用一个cpp文件来实现
MMAVReader::MMAVReader()
{
	imp = new MMAVReaderPrivate();

	//申请avFormatContext空间，记得要释放 
	//如果要读取一个视频文件，必须申请空间
	//如果再读取另外一个视频文件，则再申请一块空间
	imp->formatCtx = avformat_alloc_context();
}

MMAVReader::~MMAVReader()
{
	if (imp->formatCtx != nullptr)
	{
		//释放avFormatContext空间
		avformat_free_context(imp->formatCtx);
		imp->formatCtx = nullptr;
	}
}

int MMAVReader::Open(const char* path)
{
	if (imp->formatCtx == nullptr)
	{
		return -1;
	}

	// 打开媒体文件，path是文件路径
	int ret = avformat_open_input(&imp->formatCtx, path, nullptr, nullptr);
	
	if (!ret)
	{
		//读取媒体文件信息
		//会将媒体文件的流信息详细列出来 得到AVStream
		avformat_find_stream_info(imp->formatCtx, nullptr);
	}
	
	return ret;
}

int MMAVReader::Read(MMAVPacket* packet)
{
	if (imp->formatCtx == nullptr)
	{
		return -1;
	}

	// 该函数读取出来的数据是AVPacket
	// 对于⾳频流，⼀个AVPacket可能包含多个AVFrame
	// 对于视频流，⼀个AVPacket只包含⼀个AVFrame，
	int ret = av_read_frame(imp->formatCtx, packet->imp->pkt);

	return ret;
}

int MMAVReader::GetStreamCount()
{
	return imp->formatCtx->nb_streams;
}

int MMAVReader::GetStream(MMAVStream* avStream, int streamID)
{
	AVStream* ffmpegStream = imp->formatCtx->streams[streamID];
	avStream->streamIndex = ffmpegStream->index;

	avcodec_parameters_copy(avStream->imp->codecpar, ffmpegStream->codecpar);

	return 0;
}

int MMAVReader::GetVideoStreamIndex()
{
	return av_find_best_stream(imp->formatCtx,
		AVMediaType::AVMEDIA_TYPE_VIDEO,
		-1,
		-1,
		NULL,
		NULL);
}

int MMAVReader::GetAudioStreamIndex()
{
	return av_find_best_stream(imp->formatCtx,
		AVMediaType::AVMEDIA_TYPE_AUDIO,
		-1,
		-1,
		NULL,
		NULL);
}

int MMAVReader::CLose()
{
	if (imp->formatCtx == nullptr)
	{
		return -1;
	}

	// 关闭媒体文件
	avformat_close_input(&imp->formatCtx);
	return 0;
}